﻿#include "ngx_c_commom.h"
/***************************************************************
 * @file       nginx.cxx
 * @brief      程序入口函数
 * @author     txj
 * @version    v1
 * @return     void
 * @date       2021/7/23
 * @parameter  argc/argv
 **************************************************************/
int main(int argc, char *const *argv)
{ 
    int i = 0, exitcode = 0;
    /*标记程序是否退出*/
    g_stopEvent = 0;
    /*获取进程id*/
    ngx_pid = getpid();
    /*获取父进程id*/
    ngx_parent = getppid();

    /*统计命令行参数的字节大小*/
    g_argvneedmem = 0;
    for(i = 0; i < argc; i++)
    {
        g_argvneedmem += strlen(argv[i]) + 1;
    }
    /*统计环境变量的字节大小*/
    g_envneedmem = 0;
    for(i = 0; environ[i]; i++)
    {
        g_envneedmem += strlen(environ[i]) + 1;
    }
    /*保存下主函数的两个参数*/
    g_os_argc = argc;
    g_os_argv = (char **)argv;
    /**/
    ngx_log.fd = -1;
    /*进程类型*/
    ngx_process = NGX_PROCESS_MASTER;
    ngx_reap = 0;
    /*写日志之前，先把new一个单例类，然后把配置
    文件里面的每一项配置信息写入到这个单例类的容器里
    后续要获取某个配置信息时，去这个容器里获取就好了*/
    CConfig *p_config = CConfig::GetInstance();
    if(p_config->Load("nginx.conf") == false)
    {
        ngx_log_init();
        ngx_log_stderr(0,"配置文件%s加载失败!\n","nginx.conf");
        exitcode = 2;
        goto exitstatus;
    }
    /*单例类内存初始化*/
    CMemory::GetInstance();
    /*crc校验初始化*/
    CCRC32::GetInstance();
    /*这里其实就是打开一个文件，后续可以使用ngx_log_stderr函数往文件里写日志*/
    ngx_log_init();
    /*信号初始化*/
    if(ngx_init_signals() != 0)
    {
        ngx_log_stderr(0,"信号初始化失败！\n");
    }
    /*初始化socket*/
    if(g_socket.Initialize() == false)
    {
        exitcode = 1;
        goto exitstatus;
    }
    /*设置进程名称前的初始化工作*/
    ngx_init_setproctitle();
    /*是否按守护进程的方式运行*/
    if(p_config->GetIntDefault("Daemon",0) == 1)
    {
        int retdaemon = ngx_daemon();
        if(retdaemon == -1)
        {
            exitcode = 1;
            goto exitstatus;
        }
        else if(retdaemon == 1)
        {
            exitcode = 0;
            return exitcode;
        }
        g_daemonized = 1;
    }
    /*主进程master进程开始干活了*/
    ngx_master_process_cycle();
exitstatus:
    ngx_log_stderr(0,"程序退出！\n");
    freeresource();
    return exitcode;
}
/*
 * @file      nginx.cxx
 * @function  释放资源
 * @parameter void
 * @return    void
 * @date      2021/07/23
*/
void freeresource()
{
    //对于因为设置可执行程序标题导致的环境变量分配的内存，我们应该释放
    if(gp_envmem)
    {
        delete []gp_envmem;
        gp_envmem = NULL;
    }
    //关闭日志文件
    if(ngx_log.fd != STDERR_FILENO && ngx_log.fd != -1)  
    {        
        close(ngx_log.fd); //不用判断结果了
        ngx_log.fd = -1; //标记下，防止被再次close吧
    }
}
